﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http.Dispatcher;
using System.Web.Http.OData.Builder;
using Microsoft.Data.Edm;

namespace Disco.Web.Api.Controllers.Dynamic
{
    public class DynamicAssemblyResolver : DefaultAssembliesResolver
    {
        private const string _dynamicDllName = "Disco.Web.Api.Controllers";

        private readonly IEnumerable<EntitySetConfiguration> _entitySets;

        public DynamicAssemblyResolver(IEnumerable<EntitySetConfiguration> entitySets)
        {
            _entitySets = entitySets;
        }

        public override ICollection<Assembly> GetAssemblies()
        {
            ICollection<Assembly> baseAssemblies = base.GetAssemblies();
            List<Assembly> assemblies = new List<Assembly>(baseAssemblies);

            try
            {
                DynamicControllerGenerator generator = new DynamicControllerGenerator(_entitySets);
                Assembly dynamicAssembly = generator.CreateAssembly(_dynamicDllName);
                if (null != dynamicAssembly)
                {
                    var currentAssembly = assemblies.FirstOrDefault(assembly => assembly.FullName.StartsWith(_dynamicDllName));
                    if (null != currentAssembly)
                    {
                        var currentAssemblyVersion = currentAssembly.GetName().Version.ToString();
                        var dynamicAssemblyVersion = dynamicAssembly.GetName().Version.ToString();
                        if (!currentAssemblyVersion.Equals(dynamicAssemblyVersion))
                        {
                            assemblies.Remove(currentAssembly); 
                        }
                        else
                        {
                            dynamicAssembly = null;
                        }
                    }
                    if (null != dynamicAssembly)
                    {
                        assemblies.Add(dynamicAssembly);
                    }
                }
            }
            catch
            {
                // We ignore errors and just continue
            }

            return assemblies;
        }
    }
}